import { BuildingConfig, MapConfigs, MapSettings, ResourceConfig, UnitConfig, isResourceTildeType, SplashDamageRatio, BasePositionConfigs } from '../../battle/Const';
import { BuildingType, CommandType, EntityType, PlayerType, TildeType, UnitType } from '../../battle/Enums';
import {
    AttackCommandParam,
    BuildCommandParam,
    BuildingModel,
    CollectCommandParam,
    CommandParam,
    CommandParamMap,
    HealCommandParam,
    InitCommandParam,
    MoveCommandParam,
    SwapCommandParam,
    UnitModel,
} from '../../battle/Model';
import { LOG } from '../../ConsoleLogCtrl';
import { EntityFactory } from '../factory/EntityFactory';
import { MapManager } from '../map/MapManager';
import { Player } from './Player';

/**
 * 玩家管理器
 * 管理所有玩家数据，并提供与地图的集成操作
 */
export class PlayerManager {
    private players: Map<string, Player> = new Map();
    private entityFactory: EntityFactory;
    private mapManager: MapManager | null = null;

    constructor() {
        this.entityFactory = EntityFactory.getInstance();
    }

    /**
     * 重置玩家管理器
     */
    public reset(): void {
        this.players.clear();
        this.entityFactory.reset();
        this.mapManager = null;
    }

    /**
     * 设置地图管理器
     * @param mapManager 地图管理器实例
     */
    public setMapManager(mapManager: MapManager): void {
        this.mapManager = mapManager;
    }

    /**
     * 获取地图管理器
     * @returns 地图管理器实例
     */
    public getMapManager(): MapManager | null {
        return this.mapManager;
    }

    /**
     * 初始化玩家
     * @param playerId 玩家ID
     * @param color 玩家颜色
     * @param startPosition 起始位置
     * @param playerType 玩家类型，表示玩家是左边还是右边
     */
    public initPlayer(
        playerId: string,
        color: string,
        startPosition: { x: number; y: number },
        playerType: PlayerType
    ): Player {
        const player = new Player(playerId, color, startPosition, playerType);
        this.players.set(playerId, player);
        return player;
    }

    /**
     * 获取玩家
     * @param playerId 玩家ID
     */
    public getPlayer(playerId: string): Player | undefined {
        return this.players.get(playerId);
    }

    /**
     * 获取所有玩家
     */
    public getAllPlayers(): Player[] {
        return Array.from(this.players.values());
    }

    /**
     * 判断是否为左侧玩家（玩家1）
     * @param playerId 玩家ID
     * @returns 是否为左侧玩家
     */
    public isLeftSidePlayer(playerId: string): boolean {
        const player = this.getPlayer(playerId);
        return player ? player.isLeftSidePlayer() : false;
    }

    /**
     * 判断是否为右侧玩家（玩家2）
     * @param playerId 玩家ID
     * @returns 是否为右侧玩家
     */
    public isRightSidePlayer(playerId: string): boolean {
        const player = this.getPlayer(playerId);
        return player ? player.isRightSidePlayer() : false;
    }

    /**
     * 获取下一个可用的单位ID
     * @returns 下一个可用的单位ID
     */
    public getNextUnitId(): number {
        return this.entityFactory.getNextUnitId();
    }

    /**
     * 获取下一个可用的建筑ID
     * @returns 下一个可用的建筑ID
     */
    public getNextBuildingId(): number {
        return this.entityFactory.getNextBuildingId();
    }

    /**
     * 为玩家创建单位
     * @param playerId 玩家ID
     * @param unitType 单位类型
     * @param position 位置
     * @param unitId 可选的单位ID，如果不提供则自动生成
     * @returns 创建的单位，如果玩家不存在则返回undefined
     */
    public createUnitForPlayer(
        playerId: string,
        unitType: UnitType,
        position: { x: number; y: number },
        unitId?: number
    ): UnitModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        const unit = this.entityFactory.createUnit(playerId, unitType, position, unitId);
        player.addUnit(unit);

        return unit;
    }

    /**
     * 为玩家创建建筑
     * @param playerId 玩家ID
     * @param buildingType 建筑类型
     * @param position 位置
     * @returns 创建的建筑，如果玩家不存在则返回undefined
     */
    public createBuildingForPlayer(
        playerId: string,
        buildingType: BuildingType,
        position: { x: number; y: number },
        buildingId: number
    ): BuildingModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        const building = this.entityFactory.createBuilding(playerId, buildingType, position, buildingId);
        player.addBuilding(building);

        return building;
    }

    /**
     * 获取玩家的单位
     * @param playerId 玩家ID
     * @param unitId 单位ID
     */
    public getPlayerUnit(playerId: string, unitId: number): UnitModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        return player.getUnit(unitId);
    }

    /**
     * 获取玩家的建筑
     * @param playerId 玩家ID
     * @param buildingId 建筑ID
     */
    public getPlayerBuilding(playerId: string, buildingId: number): BuildingModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        return player.getBuilding(buildingId);
    }

    /**
     * 获取玩家的所有单位
     * @param playerId 玩家ID
     */
    public getPlayerAllUnits(playerId: string): UnitModel[] {
        const player = this.getPlayer(playerId);
        if (!player) {
            return [];
        }

        return player.getAllUnits();
    }

    /**
     * 获取玩家的所有建筑
     * @param playerId 玩家ID
     */
    public getPlayerAllBuildings(playerId: string): BuildingModel[] {
        const player = this.getPlayer(playerId);
        if (!player) {
            return [];
        }

        return player.getAllBuildings();
    }

    /**
     * 根据坐标获取建筑
     * @param position 坐标位置
     * @returns 该位置的建筑，如果不存在则返回undefined
     */
    public getBuildingByPosition(position: { x: number; y: number }): BuildingModel | undefined {
        // 遍历所有玩家
        const players = this.getAllPlayers();
        for (const player of players) {
            // 获取该玩家的所有建筑
            const buildings = player.getAllBuildings();
            // 查找坐标匹配的建筑
            const building = buildings.find((b) => b.position.x === position.x && b.position.y === position.y);
            if (building) {
                return building;
            }
        }
        return undefined;
    }

    /**
     * 根据玩家ID和坐标获取建筑
     * @param playerId 玩家ID
     * @param position 坐标位置
     * @returns 该位置的建筑，如果不存在则返回undefined
     */
    public getPlayerBuildingByPosition(playerId: string, position: { x: number; y: number }): BuildingModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        // 获取该玩家的所有建筑
        const buildings = player.getAllBuildings();
        // 查找坐标匹配的建筑
        return buildings.find((b) => b.position.x === position.x && b.position.y === position.y);
    }

    /**
     * 根据玩家ID和建筑类型获取建筑
     * @param playerId 玩家ID
     * @param buildingType 建筑类型
     * @returns 该类型的建筑，如果不存在则返回undefined
     */
    public getPlayerBuildingByType(playerId: string, buildingType: BuildingType): BuildingModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        // 获取该玩家的所有建筑
        const buildings = player.getAllBuildings();
        // 查找类型匹配的建筑
        return buildings.find((b) => b.type === buildingType);
    }

    /**
     * 根据坐标获取单位
     * @param position 坐标位置
     * @returns 该位置的单位，如果不存在则返回undefined
     */
    public getUnitByPosition(position: { x: number; y: number }): UnitModel | undefined {
        // 遍历所有玩家
        const players = this.getAllPlayers();
        for (const player of players) {
            // 获取该玩家的所有单位
            const units = player.getAllUnits();
            // 查找坐标匹配的单位
            const unit = units.find((u) => u.position.x === position.x && u.position.y === position.y);
            if (unit) {
                return unit;
            }
        }
        return undefined;
    }

    /**
     * 根据玩家ID和坐标获取单位
     * @param playerId 玩家ID
     * @param position 坐标位置
     * @returns 该位置的单位，如果不存在则返回undefined
     */
    public getPlayerUnitByPosition(playerId: string, position: { x: number; y: number }): UnitModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        // 获取该玩家的所有单位
        const units = player.getAllUnits();
        // 查找坐标匹配的单位
        return units.find((u) => u.position.x === position.x && u.position.y === position.y);
    }

    /**
     * 根据玩家ID和单位类型获取单位
     * @param playerId 玩家ID
     * @param unitType 单位类型
     * @returns 该类型的单位，如果不存在则返回undefined
     */
    public getPlayerUnitByType(playerId: string, unitType: UnitType): UnitModel | undefined {
        const player = this.getPlayer(playerId);
        if (!player) {
            return undefined;
        }

        // 获取该玩家的所有单位
        const units = player.getAllUnits();
        // 查找类型匹配的单位
        return units.find((u) => u.type === unitType);
    }

    /**
     * 处理战斗命令
     * @param command 命令数据
     * @returns 是否处理成功
     */
    public handleCommand(command: CommandParam<keyof CommandParamMap>): boolean {
        switch (command.type) {
            case CommandType.init:
                // 初始化命令
                if (command.param) {
                    const initParam = command.param as InitCommandParam;
                    // 初始化地图
                    const mapData = MapConfigs[initParam.map]
                    this.mapManager.initMap(mapData);

                    // 初始化玩家
                    if (initParam.players && initParam.players.length >= 2) {
                        const player1Id = initParam.players[0];
                        const player2Id = initParam.players[1];

                        // 设置玩家颜色
                        const player1Color = MapSettings.playerColors[0]; // 红色
                        const player2Color = MapSettings.playerColors[1]; // 蓝色

                        // 设置玩家起始位置
                        const player1StartPos = BasePositionConfigs[initParam.map][0];
                        const player2StartPos = BasePositionConfigs[initParam.map][1];

                        // 初始化玩家
                        this.initPlayer(player1Id, player1Color, player1StartPos, PlayerType.PLAYER1);
                        this.initPlayer(player2Id, player2Color, player2StartPos, PlayerType.PLAYER2);

                        // 为双方玩家构建基地
                        const base1Id = this.getNextBuildingId();
                        this.buildStructure(player1Id, -1, base1Id, player1StartPos, BuildingType.base);

                        const base2Id = this.getNextBuildingId();
                        this.buildStructure(player2Id, -1, base2Id, player2StartPos, BuildingType.base);
                    }

                }
                return true;
            case CommandType.end:
                return true;

            case CommandType.move:
                // 处理移动命令
                if (command.param) {
                    const moveParam = command.param as MoveCommandParam;
                    return this.movePlayerUnit(command.player, moveParam.self.id, moveParam.offsetPosition);
                }
                break;

            case CommandType.attack:
                // 处理攻击命令
                if (command.param) {
                    const attackParam = command.param as AttackCommandParam;
                    const attackerId = attackParam.self.id;
                    const targetPosition = attackParam.offsetPosition;
                    return this.attackTarget(command.player, attackerId, attackParam.self.type, targetPosition);
                }
                break;

            case CommandType.build:
                // 处理建造命令
                if (command.param) {
                    const buildParam = command.param as BuildCommandParam;
                    const builderId = buildParam.self.id;
                    const buildingId = buildParam.target.id;
                    const buildingType = buildParam.target.utype;
                    return this.buildStructure(command.player, builderId, buildingId, buildParam.offsetPosition, buildingType);
                }
                break;

            case CommandType.swap:
                // 处理生产单位命令
                if (command.param) {
                    const swapParam = command.param as SwapCommandParam;
                    const buildingId = swapParam.self.id;
                    const unitId = swapParam.target.id;
                    const unitType = swapParam.target.utype;
                    return this.produceUnit(command.player, buildingId, unitId, swapParam.offsetPosition, unitType);
                }
                break;

            case CommandType.heal:
                // 处理治疗命令
                if (command.param) {
                    const healParam = command.param as HealCommandParam;
                    const healerId = healParam.self.id;
                    const targetId = healParam.target.id;
                    return this.healTarget(command.player, healerId, targetId);
                }
                break;

            case CommandType.collect:
                // 处理采集命令
                if (command.param) {
                    const collectParam = command.param as CollectCommandParam;
                    return this.collectResource(
                        command.player,
                        collectParam.self.id,
                        collectParam.target.id,
                        collectParam.offsetPosition
                    );
                }
                break;
        }

        LOG.error('处理命令失败:', command);
        return false;
    }

    /**
     * 治疗目标
     * @param playerId 玩家ID
     * @param healerId 治疗者ID
     * @param targetId 目标ID
     * @returns 是否治疗成功
     */
    private healTarget(playerId: string, healerId: number, targetId: number): boolean {
        // 获取治疗者
        const healer = this.getPlayerUnit(playerId, healerId);
        if (!healer) {
            LOG.error('处理治疗命令失败：找不到治疗者', healerId);
            return false;
        }

        // 查找目标单位（治疗只能对友军进行，所以直接在治疗者的玩家中查找）
        const player = this.getPlayer(playerId);
        if (!player) {
            LOG.error('处理治疗命令失败：找不到玩家', playerId);
            return false;
        }

        const unit = player.getUnit(targetId);
        if (!unit) {
            LOG.error('处理治疗命令失败：找不到目标', targetId);
            return false;
        }

        // 检查治疗距离是否在允许范围内（只允许四个方向治疗，不允许斜向治疗）
        const deltaX = Math.abs(unit.position.x - healer.position.x);
        const deltaY = Math.abs(unit.position.y - healer.position.y);
        const maxHealRange = UnitConfig[healer.type]?.attackRange || 1;

        // 检查是否为斜向治疗（不允许斜向治疗）
        if (deltaX !== 0 && deltaY !== 0) {
            LOG.error('治疗目标失败：不允许斜向治疗', deltaX, deltaY);
            return false;
        }

        // 检查治疗距离是否超出范围
        if (deltaX > maxHealRange || deltaY > maxHealRange) {
            LOG.error('治疗目标失败：治疗距离超出允许范围', deltaX, deltaY, '最大距离:', maxHealRange);
            return false;
        }

        // 增加目标血量
        const healValue = healer.attack; // 使用攻击力作为治疗量
        unit.hp += healValue;
        LOG.log(`单位受到治疗：ID=${unit.id}, 当前血量=${unit.hp}`);
        return true;
    }

    /**
     * 计算溅射目标位置
     * @param targetPosition 被攻击目标的位置
     * @param offsetPosition 攻击方向偏移量
     * @returns 溅射目标位置数组
     */
    private calculateSplashPositions(targetPosition: { x: number; y: number }, offsetPosition: { x: number; y: number }): { x: number; y: number }[] {
        // 根据攻击方向计算溅射目标位置
        // 如果攻击方向是(1,0)，则溅射位置是(1,1)和(1,-1)
        // 如果攻击方向是(0,1)，则溅射位置是(1,1)和(-1,1)
        // 如果攻击方向是(-1,0)，则溅射位置是(-1,1)和(-1,-1)
        // 如果攻击方向是(0,-1)，则溅射位置是(1,-1)和(-1,-1)
        const splashPositions: { x: number; y: number }[] = [];

        if (offsetPosition.x !== 0) {
            // 水平攻击，溅射到上下两个位置
            splashPositions.push(
                { x: targetPosition.x, y: targetPosition.y + 1 },
                { x: targetPosition.x, y: targetPosition.y - 1 }
            );
        } else if (offsetPosition.y !== 0) {
            // 垂直攻击，溅射到左右两个位置
            splashPositions.push(
                { x: targetPosition.x + 1, y: targetPosition.y },
                { x: targetPosition.x - 1, y: targetPosition.y }
            );
        }

        return splashPositions;
    }

    /**
     * 处理溅射伤害逻辑
     * @param attackerEntity 攻击者实体
     * @param targetPosition 目标位置
     * @param offsetPosition 攻击方向偏移量
     * @param attackerPlayerId 攻击者玩家ID
     */
    private applySplashDamage(attackerEntity: UnitModel | BuildingModel, targetPosition: { x: number; y: number }, offsetPosition: { x: number; y: number }, attackerPlayerId: string): void {
        const splashDamage = Math.floor(attackerEntity.attack * SplashDamageRatio);

        // 计算溅射目标位置
        const splashPositions = this.calculateSplashPositions(targetPosition, offsetPosition);

        // 对溅射位置的敌方单位造成伤害
        for (const splashPos of splashPositions) {
            // 检查位置是否在地图范围内
            if (!this.mapManager) {
                continue;
            }

            const splashTile = this.mapManager.getTile(splashPos.x, splashPos.y);
            if (!splashTile || splashTile.entityId === undefined || splashTile.entityType !== EntityType.unit) {
                continue;
            }

            // 只对敌方单位造成溅射伤害
            if (splashTile.playerId === attackerPlayerId) {
                continue;
            }

            // 获取溅射目标单位
            const splashPlayer = this.getPlayer(splashTile.playerId);
            if (!splashPlayer) {
                continue;
            }

            const splashUnit = splashPlayer.getUnit(splashTile.entityId);
            if (!splashUnit) {
                continue;
            }

            // 对溅射目标造成伤害
            splashUnit.hp -= splashDamage;
            LOG.log(`溅射伤害：单位ID=${splashUnit.id}, 伤害=${splashDamage}, 剩余血量=${splashUnit.hp}`);

            // 如果溅射导致单位死亡
            if (splashUnit.hp <= 0) {
                LOG.log(`溅射击杀：单位ID=${splashUnit.id}`);

                // 给击杀方增加击杀奖励
                const attackerPlayer = this.getPlayer(attackerPlayerId);
                if (attackerPlayer) {
                    const unitConfig = UnitConfig[splashUnit.type];
                    if (unitConfig && unitConfig.killedAward) {
                        attackerPlayer.addRmb(unitConfig.killedAward);
                    }
                }

                // 从玩家数据中移除单位
                splashPlayer.removeUnit(splashUnit.id);

                // 从地图中移除单位
                this.mapManager.removeEntity(splashPos.x, splashPos.y);
            }
        }
    }

    /**
     * 采集资源
     * @param playerId 玩家ID
     * @param collecterId 采集者ID
     * @param targetId 目标资源ID
     * @param offsetPosition 位置偏移量
     * @returns 是否采集成功
     */
    private collectResource(
        playerId: string,
        collecterId: number,
        targetId: number,
        offsetPosition: { x: number; y: number }
    ): boolean {
        // 获取采集者
        const collector = this.getPlayerUnit(playerId, collecterId);
        if (!collector) {
            LOG.error('处理采集命令失败：找不到采集者', collecterId);
            return false;
        }

        // 计算目标位置
        const targetPosition = {
            x: collector.position.x + offsetPosition.x,
            y: collector.position.y + offsetPosition.y,
        };

        // 检查采集距离是否在允许范围内（只允许四个方向采集，不允许斜向采集）
        const deltaX = Math.abs(offsetPosition.x);
        const deltaY = Math.abs(offsetPosition.y);
        const maxCollectRange = UnitConfig[collector.type]?.attackRange || 1;

        // 检查是否为斜向采集（不允许斜向采集）
        if (deltaX !== 0 && deltaY !== 0) {
            LOG.error('采集资源失败：不允许斜向采集', deltaX, deltaY);
            return false;
        }

        // 检查采集距离是否超出范围
        if (deltaX > maxCollectRange || deltaY > maxCollectRange) {
            LOG.error('采集资源失败：采集距离超出允许范围', deltaX, deltaY, '最大距离:', maxCollectRange);
            return false;
        }

        // 获取目标位置的资源类型
        const tileInfo = this.mapManager.getTile(targetPosition.x, targetPosition.y);
        if (!tileInfo) {
            LOG.error('采集资源失败：目标位置无效', targetPosition);
            return false;
        }

        // 检查目标位置是否有资源
        if (!isResourceTildeType(tileInfo.tileType)) {
            LOG.error('采集资源失败：目标位置没有可采集的资源', tileInfo.tileType);
            return false;
        }

        // 获取资源配置
        const resourceConfig = ResourceConfig[tileInfo.tileType];
        if (!resourceConfig) {
            LOG.error('采集资源失败：无法获取资源配置', tileInfo.tileType);
            return false;
        }

        // 计算采集量（采集兵的attack值作为采集能力）
        const collectAmount = collector.attack * resourceConfig.value;

        // 获取玩家并增加资源
        const player = this.getPlayer(playerId);
        if (player) {
            player.addRmb(collectAmount);
            LOG.log(`采集命令：采集者ID=${collecterId}, 资源类型=${resourceConfig.name}, 采集量=${collectAmount}`);
            return true;
        }

        LOG.error('采集资源失败：找不到玩家', playerId);
        return false;
    }

    /**
     * 建造结构并更新地图
     * @param playerId 玩家ID
     * @param builderId 建造者单位ID
     * @param buildingId 建筑ID
     * @param offsetPosition 位置偏移量
     * @param buildingType 建筑类型
     * @returns 是否建造成功
     */
    public buildStructure(
        playerId: string,
        builderId: number,
        buildingId: number,
        offsetPosition: { x: number; y: number },
        buildingType: BuildingType
    ): boolean {
        if (!this.mapManager) {
            LOG.error('[PlayerManager] 地图管理器未设置');
            return false;
        }

        // 创建的建筑是否已存在
        if (this.getPlayerBuilding(playerId, buildingId)) {
            LOG.error('[PlayerManager] 建造失败：建筑已存在', buildingId);
            return false;
        }

        // 获取建筑成本
        const buildingConfig = BuildingConfig[buildingType];
        if (!buildingConfig) {
            LOG.error('[PlayerManager] 建造失败：无法获取建筑配置', buildingType);
            return false;
        }

        // 检查玩家资源是否足够
        const player = this.getPlayer(playerId);
        if (!player) {
            LOG.error('[PlayerManager] 建造失败：找不到玩家', playerId);
            return false;
        }

        let position = {
            x: offsetPosition.x,
            y: offsetPosition.y,
        };

        if (buildingType !== BuildingType.base) {
            // 获取建造者单位
            const builder = this.getPlayerUnit(playerId, builderId);
            if (!builder) {
                LOG.error('[PlayerManager] 建造失败：找不到建造者单位', builderId);
                return false;
            }

            // 检查建造距离是否在允许范围内（只允许四个方向建造，不允许斜向建造）
            const deltaX = Math.abs(offsetPosition.x);
            const deltaY = Math.abs(offsetPosition.y);
            const maxBuildRange = UnitConfig[builder.type]?.attackRange || 1;

            // 检查是否为斜向建造（不允许斜向建造）
            if (deltaX !== 0 && deltaY !== 0) {
                LOG.error('[PlayerManager] 建造失败：不允许斜向建造', deltaX, deltaY);
                return false;
            }

            // 检查建造距离是否超出范围
            if (deltaX > maxBuildRange || deltaY > maxBuildRange) {
                LOG.error('[PlayerManager] 建造失败：建造距离超出允许范围', deltaX, deltaY, '最大距离:', maxBuildRange);
                return false;
            }

            // 计算建筑的实际位置（建造者位置 + 偏移量）
            position.x = builder.position.x + offsetPosition.x;
            position.y = builder.position.y + offsetPosition.y;
        }

        // 创建新建筑，使用提供的buildingId
        let building = this.createBuildingForPlayer(playerId, buildingType, position, buildingId);
        if (!building) {
            LOG.error('[PlayerManager] 建造失败：无法创建建筑', buildingType);
            return false;
        }

        // 基地不需要扣除资源，其他建筑需要
        if (buildingType !== BuildingType.base) {
            const buildCost = buildingConfig.cost;
            if (!player.deductRmb(buildCost)) {
                LOG.error('[PlayerManager] 建造失败：资源不足', buildCost);
                return false;
            }
        }

        // 更新地图
        this.mapManager.placeEntity({
            x: position.x,
            y: position.y,
            tileType: TildeType.flat,
            playerId: playerId,
            entityType: EntityType.building,
            entityId: building.id,
            buildingType: building.type,
        });

        return true;
    }

    /**
     * 生产单位并更新地图
     * @param playerId 玩家ID
     * @param buildingId 生产建筑ID
     * @param unitId 单位ID
     * @param offsetPosition 位置偏移量
     * @param unitType 单位类型
     * @returns 是否生产成功
     */
    public produceUnit(
        playerId: string,
        buildingId: number,
        unitId: number,
        offsetPosition: { x: number; y: number },
        unitType: UnitType
    ): boolean {
        if (!this.mapManager) {
            LOG.error('地图管理器未设置');
            return false;
        }

        // 获取生产建筑
        const building = this.getPlayerBuilding(playerId, buildingId);
        if (!building) {
            LOG.error('生产失败：找不到建筑', buildingId);
            return false;
        }

        // 创建的单位是否已存在
        if (this.getPlayerUnit(playerId, unitId)) {
            LOG.error('生产失败：单位已存在', unitId);
            return false;
        }

        // 获取单位成本
        const unitConfig = UnitConfig[unitType];
        if (!unitConfig) {
            LOG.error('生产失败：无法获取单位配置', unitType);
            return false;
        }

        // 检查玩家资源是否足够
        const player = this.getPlayer(playerId);
        if (!player) {
            LOG.error('生产失败：找不到玩家', playerId);
            return false;
        }

        // 检查生产距离是否在允许范围内（只允许四个方向生产，不允许斜向生产）
        const deltaX = Math.abs(offsetPosition.x);
        const deltaY = Math.abs(offsetPosition.y);
        const buildingConfig = BuildingConfig[building.type];
        const maxProduceRange = buildingConfig ? buildingConfig.attackRange : 1; // 使用基地的攻击范围作为生产范围

        // 检查生产距离是否在允许范围内（允许斜向生产）
        if (deltaX > maxProduceRange || deltaY > maxProduceRange) {
            LOG.error('生产失败：生产距离超出允许范围', Math.max(deltaX, deltaY), '最大距离:', maxProduceRange);
            return false;
        }

        // 计算单位的实际位置（建筑位置 + 偏移量）
        const position = {
            x: building.position.x + offsetPosition.x,
            y: building.position.y + offsetPosition.y,
        };

        // 创建新单位，使用提供的unitId
        let unit = this.createUnitForPlayer(playerId, unitType, position, unitId);
        if (!unit) {
            LOG.error('生产失败：无法创建单位', unitType);
            return false;
        }

        const unitCost = unitConfig.cost;
        if (!player.deductRmb(unitCost)) {
            LOG.error('生产失败：资源不足', unitCost);
            return false;
        }

        // 更新地图
        this.mapManager.placeEntity({
            x: position.x,
            y: position.y,
            tileType: TildeType.flat,
            playerId: playerId,
            entityType: EntityType.unit,
            entityId: unit.id,
            unitType: unit.type,
        });

        return true;
    }

    /**
     * 移动玩家单位并更新地图
     * @param playerId 玩家ID
     * @param unitId 单位ID
     * @param offsetPosition 位置偏移量
     * @returns 是否移动成功
     */
    public movePlayerUnit(playerId: string, unitId: number, offsetPosition: { x: number; y: number }): boolean {
        if (!this.mapManager) {
            LOG.error('地图管理器未设置');
            return false;
        }

        // 获取单位
        const unit = this.getPlayerUnit(playerId, unitId);
        if (!unit) {
            LOG.error('移动单位失败：找不到单位', unitId);
            return false;
        }

        // 计算目标位置
        const targetPosition = {
            x: unit.position.x + offsetPosition.x,
            y: unit.position.y + offsetPosition.y,
        };

        // 检查移动距离是否在允许范围内（只允许四个方向移动，不允许斜向移动）
        const deltaX = Math.abs(offsetPosition.x);
        const deltaY = Math.abs(offsetPosition.y);
        const maxMoveDistance = UnitConfig[unit.type]?.speed || 1;

        // 检查是否为斜向移动（不允许斜向移动）
        if (deltaX !== 0 && deltaY !== 0) {
            LOG.error('移动单位失败：不允许斜向移动', deltaX, deltaY);
            return false;
        }

        // 检查移动距离是否超出范围
        if (deltaX > maxMoveDistance || deltaY > maxMoveDistance) {
            LOG.error('移动单位失败：移动距离超出允许范围', deltaX, deltaY, '最大距离:', maxMoveDistance);
            return false;
        }

        // 移动单位
        const result = this.mapManager.moveEntity(unit.position.x, unit.position.y, targetPosition.x, targetPosition.y);

        // 更新单位位置
        if (result) {
            unit.position = { ...targetPosition };
        }

        return result;
    }

    /**
     * 攻击目标并更新地图
     * @param playerId 攻击方玩家ID
     * @param attackerId 攻击者ID（可以是单位或建筑）
     * @param attackerType 攻击者类型（单位或建筑）
     * @param offsetPosition 位置偏移量
     * @returns 是否攻击成功
     */
    public attackTarget(playerId: string, attackerId: number, attackerType: EntityType, offsetPosition: { x: number; y: number }): boolean {
        if (!this.mapManager) {
            LOG.error('地图管理器未设置');
            return false;
        }

        // 根据攻击者类型获取攻击者实体
        let attackerEntity;
        let maxAttackRange = 1;

        if (attackerType === EntityType.unit) {
            // 获取单位
            const unit = this.getPlayerUnit(playerId, attackerId);
            if (!unit) {
                LOG.error('攻击目标失败：找不到攻击者单位', attackerId);
                return false;
            }
            attackerEntity = unit;
            maxAttackRange = UnitConfig[unit.type]?.attackRange || 1;
        } else if (attackerType === EntityType.building) {
            // 获取建筑
            const building = this.getPlayerBuilding(playerId, attackerId);
            if (!building) {
                LOG.error('攻击目标失败：找不到攻击者建筑', attackerId);
                return false;
            }
            attackerEntity = building;
            maxAttackRange = BuildingConfig[building.type]?.attackRange || 1;
        } else {
            LOG.error('攻击目标失败：无效的攻击者类型', attackerType);
            return false;
        }

        // 计算目标位置
        const targetPosition = {
            x: attackerEntity.position.x + offsetPosition.x,
            y: attackerEntity.position.y + offsetPosition.y
        };

        // 检查攻击距离是否在允许范围内（只允许四个方向攻击，不允许斜向攻击）
        const deltaX = Math.abs(offsetPosition.x);
        const deltaY = Math.abs(offsetPosition.y);

        // 检查是否为斜向攻击（不允许斜向攻击）
        if (deltaX !== 0 && deltaY !== 0) {
            LOG.error('攻击目标失败：不允许斜向攻击', deltaX, deltaY);
            return false;
        }

        // 检查攻击距离是否超出范围
        if (deltaX > maxAttackRange || deltaY > maxAttackRange) {
            LOG.error('攻击目标失败：攻击距离超出允许范围', deltaX, deltaY, '最大距离:', maxAttackRange);
            return false;
        }

        // 检查攻击路径上是否有阻隔（当攻击范围大于1时）
        if (maxAttackRange > 1) {
            // 检查攻击路径上是否有障碍物
            if (offsetPosition.x !== 0) {
                const step = offsetPosition.x > 0 ? 1 : -1;
                for (let x1 = attackerEntity.position.x + step; x1 !== targetPosition.x; x1 += step) {
                    const checkPos = { x: x1, y: targetPosition.y };
                    const checkTile = this.mapManager.getTile(checkPos.x, checkPos.y);

                    // 检查地形是否为平地或河流
                    if (checkTile && checkTile.tileType !== TildeType.flat && checkTile.tileType !== TildeType.river) {
                        LOG.error('攻击目标失败：攻击路径上有非平地地形阻隔', checkPos);
                        return false;
                    }
                }
            } else if (offsetPosition.y !== 0) {
                const step = offsetPosition.y > 0 ? 1 : -1;
                for (let y1 = attackerEntity.position.y + step; y1 !== targetPosition.y; y1 += step) {
                    const checkPos = { x: targetPosition.x, y: y1 };
                    const checkTile = this.mapManager.getTile(checkPos.x, checkPos.y);

                    // 检查地形是否为平地或河流
                    if (checkTile && checkTile.tileType !== TildeType.flat && checkTile.tileType !== TildeType.river) {
                        LOG.error('攻击目标失败：攻击路径上有非平地或河流地形阻隔', checkPos);
                        return false;
                    }
                }
            }
        }

        // 获取目标位置的地图格子
        const targetTile = this.mapManager.getTile(targetPosition.x, targetPosition.y);
        if (!targetTile || targetTile.entityId === undefined) {
            LOG.error('攻击目标失败：目标位置没有实体', targetPosition);
            return false;
        }

        // 检查目标是否是对手实体
        if (targetTile.playerId === playerId) {
            LOG.error('攻击目标失败：不能攻击自己的实体', targetTile);
            return false;
        }

        // 获取攻击者的攻击力
        const attackValue = attackerEntity.attack;

        // 获取目标实体
        let targetEntity;
        let targetPlayer;

        // 直接通过目标位置信息获取目标实体
        targetPlayer = this.getPlayer(targetTile.playerId);
        if (!targetPlayer) {
            LOG.error('攻击目标失败：找不到目标玩家', targetTile.playerId);
            return false;
        }

        if (targetTile.entityType === EntityType.unit) {
            targetEntity = targetPlayer.getUnit(targetTile.entityId);
        } else if (targetTile.entityType === EntityType.building) {
            targetEntity = targetPlayer.getBuilding(targetTile.entityId);
        }

        if (!targetEntity) {
            LOG.error('攻击目标失败：找不到目标实体', targetTile.entityId);
            return false;
        }

        // 扣除目标实体的血量
        targetEntity.hp -= attackValue;
        LOG.log(`实体受到攻击：ID=${targetEntity.id}, 剩余血量=${targetEntity.hp}`);

        // 如果血量为0或以下，移除目标实体
        if (targetEntity.hp <= 0) {
            LOG.log(`实体被摧毁：ID=${targetEntity.id}`);

            // 给击杀方增加击杀奖励
            const attackerPlayer = this.getPlayer(playerId);
            if (attackerPlayer) {
                let killReward = 0;

                if (targetTile.entityType === EntityType.unit) {
                    const unitConfig = UnitConfig[targetEntity.type as UnitType];
                    if (unitConfig && unitConfig.killedAward) {
                        killReward = unitConfig.killedAward;
                    }
                } else if (targetTile.entityType === EntityType.building) {
                    const buildingConfig = BuildingConfig[targetEntity.type as BuildingType];
                    if (buildingConfig && buildingConfig.killedAward) {
                        killReward = buildingConfig.killedAward;
                    }
                }

                if (killReward > 0) {
                    attackerPlayer.addRmb(killReward);
                }
            }

            // 从玩家数据中移除实体
            if (targetTile.entityType === EntityType.unit) {
                targetPlayer.removeUnit(targetEntity.id);
            } else if (targetTile.entityType === EntityType.building) {
                targetPlayer.removeBuilding(targetEntity.id);
            }

            // 从地图中移除实体
        const removeResult = this.mapManager.removeEntity(targetPosition.x, targetPosition.y);
        
        // 如果攻击者是士兵类型，处理溅射伤害
        if (attackerType === EntityType.unit && attackerEntity.type === UnitType.soldier) {
            this.applySplashDamage(attackerEntity, targetPosition, offsetPosition, playerId);
        }
        
        return removeResult;
    }
    
    // 如果攻击者是士兵类型，处理溅射伤害
    if (attackerType === EntityType.unit && attackerEntity.type === UnitType.soldier) {
        this.applySplashDamage(attackerEntity, targetPosition, offsetPosition, playerId);
    }

    return true;
}
}
